package com.warmheart.base.filter;

import java.io.IOException;
import java.util.Date;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.warmheart.base.executor.TraceContext;
import com.warmheart.core.enums.ResultCode;
import com.warmheart.core.result.CommonResult;
import com.warmheart.core.util.JsonResponseUtil;

/**
 * 
 * @ClassName: PreHandlerFilter
 * @Description: 预处理过滤器
 * @author ZhangJianyang
 * @date 2025-06-16 09:37:02
 *
 */
public class PreHandlerFilter implements Filter {

    private static Logger logger = LoggerFactory.getLogger(PreHandlerFilter.class);

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        Date startTime = new Date();
        String preSpanId = TraceContext.getSpan();
        TraceContext.setSpan();
        logger.info("----------------------------预处理开始----------------------------");
        HttpServletResponse hResponse = null;
        try {
            if (request instanceof HttpServletRequest) {
                HttpServletRequest hRequest = (HttpServletRequest) request;
                hResponse = (HttpServletResponse) response;
                chain.doFilter(hRequest, hResponse);
            } else {
                chain.doFilter(request, response);
            }
        } catch (Exception e) {
            // 这里是最后一层过滤器，在此之前Controller异常已被切面处理，这里只会捕获包括拦截器异常在内的SERVLET异常
            logger.error("预处理过滤器处理失败：" + e.getMessage(), e);
            if (hResponse != null) {
                JsonResponseUtil.writerJsonFromObj(hResponse, CommonResult.failed(ResultCode.INVALID_REQUEST));
            }
        } finally {
            Long nextSpanCost = TraceContext.getSpanCost();
            Date endTime = new Date();
            Long currSpanCost = endTime.getTime() - startTime.getTime() - nextSpanCost;
            logger.info("预处理耗时{}ms", currSpanCost);
            logger.info("----------------------------预处理结束----------------------------");
            TraceContext.resetSpanCost(endTime.getTime() - startTime.getTime());
            TraceContext.resetSpan(preSpanId);
        }
    }
}
